package src.main.mingling;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

public class Client { //命令发起者
    public static void main(String[] args) {
        Invoker invoker = new Invoker();
        invoker.setCommand(new ConcreteCommand(new Receiver1())); //执行对象
        ArrayList list1=new ArrayList();
        invoker.executeCommand("execute1",list1); //执行对象是方法
        list1.add("执行test1");
        invoker.executeCommand("test1",list1);

        invoker.setCommand(new ConcreteCommand(new Receiver2()));
        ArrayList list2=new ArrayList();
        invoker.executeCommand("execute2",null);
        list2.add(666);
        invoker.executeCommand("test2",list2);

    }
}

abstract class Command<T> {
    protected T receiver;  // 命令真正的执行者

    public Command(T receiver) {
        this.receiver = receiver;
    }
    public abstract void execute(String methodName, ArrayList list); // 延迟到子类实现
}

class ConcreteCommand<T> extends Command<T> { //绑定命令与执行者

    public ConcreteCommand(T receiver) {
        super(receiver);
    }

    @Override
    public void execute(String methodName, ArrayList list) {
        try {
            if(list==null){
                receiver.getClass().getMethod(methodName).invoke(receiver);
            }else {
                int index = list.size();
                switch (index) {
                    case 1:
                        receiver.getClass().getMethod(methodName, list.get(0).getClass()).invoke(receiver, list.get(0)); //通过反射动态设置绑定的执行者
                        break;
                    case 2:
                        receiver.getClass().getMethod(methodName, list.get(0).getClass(), list.get(1).getClass()).invoke(receiver, list.get(0), list.get(1));
                        break;
                    case 3:
                        receiver.getClass().getMethod(methodName, list.get(0).getClass(), list.get(1).getClass(), list.get(2).getClass()).invoke(receiver, list.get(0), list.get(1), list.get(2));
                        break;
                    default:
                        receiver.getClass().getMethod(methodName).invoke(receiver);
                        break;
                }
            }

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

class Invoker {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void executeCommand(String methodName, ArrayList list) {
        command.execute(methodName,list);
    }
}

class Receiver1 {  //接受命令执行者1
    public void execute1() {
        System.out.println("执行1成功！");
    }
    public void test1(String str){
        System.out.println("执行：Receiver1.test1(String str)----:"+str);
    }
}
class Receiver2 {  //接受命令执行者2
    public void execute2() {
        System.out.println("执行2成功！");
    }
    public void test2(Integer t){
        System.out.println("执行：Receiver2.test2(int t)----:"+t);
    }
}